In [1]:
%%HTML
<style>
div#notebook-container.container {
/* This acts as a spacer between cells,
that is outside the border */
margin: 2px 0px 2px 0px;
list-style: none;
padding: 0;
margin: 0;
-ms-box-orient: horizontal;
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -moz-flex;
display: -webkit-flex;
display: flex;
justify-content: space-around;
-webkit-flex-wrap: wrap;
flex-wrap: wrap;
-webkit-flex-direction: row;
flex-direction: row;
}
div.cell {
width:550px
}
</style>
The code on the left is a hack to make this notebook two-column. I found it here:
http://stackoverflow.com/questions/23370670/ipython-notebook-put-code-cells-into-columns
Welcome to the OOP-session of our Python course! This notebook introduces Python's OOP-concepts in a two column-style side by side with an equivalent formulation in Java respectively.
We chose Java here, as it is a popular OOP-enabled language that many of you are probably familiar with. Also, we found it helpful to compare Python-style to some other language and Java-OOP is still somewhat easier to read than OOP in C-ish languages.
class SpaceShip(SpaceObject):
bgColor = (0, 0, 0, 0)
def __init__(color, position):
super(SpaceShip, self).__init__(
position)
self.color = color
def fly(self, moveVector):
self.position += moveVector
@staticmethod
def get_bgColor():
return SpaceShip.bgColor
See https://julien.danjou.info/blog/2013/guide-python-static-class-abstract-methods for a guide about the decorators @staticmethod
, @classmethod
and abstractmethod
.
Classmethods have no equivalent in Java. They are like special static methods that get the class as their initial, implicit argument:
@classmethod
def get_bgColor(cls):
return cls.bgColor
public class SpaceShip extends SpaceObject {
public static Color bgColor =
new Color(0, 0, 0, 0);
public Color color;
public SpaceShip(Color col, Vec3D pos) {
super(pos);
color = col;
}
public void fly(Vec3D move) {
position.add(move);
}
public static Color get_bgColor() {
return bgColor;
}
}
from abc import ABCMeta
class Target():
__metaclass__ = ABCMeta
@abstractmethod
def hit(self, strength):
pass
public interface Target {
public void hit(double strength);
}
//or
public abstract class Target {
public abstract void hit(double strength);
}
class SpaceShip(SpaceObject, Target):
def hit(self, strength):
print "Damn I'm hit."
public class SpaceShip extends SpaceObject
implements Target {
public void hit(double strength) {
System.out.println("Damn I'm hit.");
}
}
class Hitpoints(Target):
def __init__(self):
self.hitpoints = 100
def hit(self, strength):
self.hitpoints -= strength
class SpaceShip(SpaceObject, Hitpoints):
def __init__(self):
Hitpoints.__init__(self)
super(SpaceShip, self).__init__()
public class HitpointSpaceShip extends
SpaceShip implements Hitpoints {
double hitpoints = 100.0;
}
public interface Hitpoints extends Target {
//Java 8 introduced default-implementations:
default void hit(double strength) {
((HitpointSpaceShip) this).hitpoints -=
strength;
}
}
class Fraction():
def __init__(self, numerator,denominator):
self.num = numerator
self.den = denominator
def __mul__(self, other):
return Fraction(self.num * other.num,
self.den * other.den)
Overview of magic methods:
Original essay about new-style classes by Guido van Rossum: https://www.python.org/download/releases/2.2.3/descrintro/
New-style class:
In [31]:
class classA():
pass
a = classA()
print type(a)
In [32]:
class classA(object):
pass
a = classA()
print type(a)
In [33]:
class evenInt(int):
def __init__(self, value):
if value % 2 != 0:
raise ValueError(str(value)+
' is not even')
super(evenInt, self).__init__(value)
a = evenInt(24)
b = 9
a+b
Out[33]:
In [30]:
class defaultdict(dict):
def __init__(self, default=None):
dict.__init__(self)
self.default = default
def __getitem__(self, key):
try:
return dict.__getitem__(self, key)
except KeyError:
return self.default
a = defaultdict(default=0.0)
print a
a['x1'] = 1
print a['x1']
print a
print a['x2']
a.y = '7'
print a.y
print a.__dict__
In [3]:
class defaultdict(dict):
__slots__ = ['default']
def __init__(self, default=None):
dict.__init__(self)
self.default = default
def __getitem__(self, key):
try:
return dict.__getitem__(self, key)
except KeyError:
return self.default
a = defaultdict(default=0.0)
print a
a['x1'] = 1
print a['x1']
print a
print a['x2']
#a.y = '7'
#print a.y
#print a.__dict__
print a.__slots__
In [2]:
class defaultdict(dict):
__slots__ = ['default']
def __init__(self, default=None):
dict.__init__(self)
self.default = default
def __getitem__(self, key):
try:
return dict.__getitem__(self, key)
except KeyError:
return self.default
a = defaultdict(default=0.0)
print a
a['x1'] = 1
print a['x1']
print a
print a['x2']
#a.y = '7'
#print a.y
#print a.__dict__
print a.__slots__
a.__slots__.append('y')
print a.__slots__
a.y = '7'
print a.y
Some notes on slots:
__slot__
subclasses
In [ ]: